﻿using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class ArticleSlot : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler {

    public GameObject ArticleItemPrefab;
    /// <summary>
    /// 格子是否装满了
    /// </summary>
    public bool IsFull { get; private set; }
    public ArticleInfo ArticleInfo = new ArticleInfo();
    public Constant.ArticleCategory ArticleCategory;

    private ArticleItem _articleItem;
    /// <summary>
    /// 格子中的物品
    /// </summary>
    public ArticleItem ArticleItem {
        get {
            if (this._articleItem == null) {
                this._articleItem = GetComponentInChildren<ArticleItem>();
            }
            return this._articleItem;
        }
    }
    private Text _placeholderText;
    /// <summary>
    /// 提示
    /// </summary>
    public Text PlaceholderText {
        get {
            if (this._placeholderText == null) {
                this._placeholderText = GetComponentInChildren<Text>();
            }
            return this._placeholderText;
        }
    }

    /// <summary>
    /// 存放物品
    /// 如果没有物品，则添加物品；
    /// 如果有物品，则添加数量
    /// </summary>
    /// <param name="article">物品</param>
    /// <param name="amount">数量</param>
    /// <returns>溢出量</returns>
    public int StoreArticle(Article article, int amount = 1) {
        int overflow;
        ArticleItem articleItem;
        if (this.IsEmpty()) {
            GameObject gameObject = Instantiate(this.ArticleItemPrefab);
            gameObject.transform.SetParent(this.transform, false);
            articleItem = gameObject.GetComponent<ArticleItem>();
            overflow = this.SetArticle(articleItem, article, amount);
        } else {
            articleItem = this.transform.GetChild(1).GetComponent<ArticleItem>();
            overflow = this.AddAmount(articleItem, amount);
        }
        return overflow;
    }

    public int StoreArticle(ArticleInfo articleInfo) {
        return this.StoreArticle(articleInfo.Article, articleInfo.Amount);
    }

    public int SetArticle(ArticleItem articleItem, Article article, int amount) {
        int overflow = articleItem.SetArticle(article, amount);
        this.IsFull = overflow >= 0;
        SetArticleInfo(articleItem.ArticleInfo);
        return overflow;
    }

    public int AddAmount(ArticleItem articleItem, int amount) {
        int overflow = articleItem.AddAmount(amount);
        this.IsFull = overflow >= 0;
        SetArticleInfo(articleItem.ArticleInfo);
        return overflow;
    }

    public int ReduceAmount(ArticleItem articleItem, int amount) {
        int residue = articleItem.ReduceAmount(amount);
        if (amount > 0) { // 如果容量减少了，就不是满的
            this.IsFull = false;
        }
        return residue;
    }

    /// <summary>
    /// 清空物品
    /// </summary>
    public void ClearArticle() {
        Destroy(this._articleItem.gameObject);
        this._articleItem = null;
        SetArticleInfo(null, 0);
        this.IsFull = false;
    }

    public void SetArticleInfo(ArticleInfo articleInfo) {
        this.SetArticleInfo(articleInfo.Article, articleInfo.Amount);
    }

    public void SetArticleInfo(Article article, int amount) {
        this.ArticleInfo.Article = article;
        this.ArticleInfo.Amount = amount;
    }

    /// <summary>
    /// 格子是否是空的
    /// </summary>
    /// <returns></returns>
    public bool IsEmpty() {
        return this.transform.childCount == 1;
    }

    /// <summary>
    /// 格子里是否有东西
    /// </summary>
    /// <returns></returns>
    public bool IsNotEmpty() {
        return !this.IsEmpty();
    }

    /// <summary>
    /// 拿出该格子所有物品
    /// </summary>
    /// <returns>拿起的物品数量</returns>
    public int PickUpALL() {
        ArticleItem articleItem = this.ArticleItem;
        articleItem.PickUpAll();
        return articleItem.ArticleInfo.Amount;
    }

    /// <summary>
    /// 拿出该格子一半物品，如果只有1个，则全部拿出
    /// </summary>
    /// <returns>拿起的物品数量</returns>
    public int PickUpHalf() {
        ArticleItem articleItem = this.ArticleItem;
        int amount = (articleItem.ArticleInfo.Amount + 1) / 2;
        if (amount == articleItem.ArticleInfo.Amount) { // 如果拿出了所有的
            articleItem.PickUpAll();
        } else { // 没有拿出所有，则物品格数量减少
            articleItem.GetArticleSlot().ReduceAmount(articleItem, amount);
        }
        return amount;
    }

    /// <summary>
    /// 放下物品
    /// 如果是全部拿出来，最后都会放下
    ///     如果格子是空的，则把物品放入到当前格子，之前的格子置空。（如果之前/当前格子是装备格子，则更新人物属性）
    ///     如果格子不是空的，则进行判断
    ///         如果格子是将所有物品取出来的格子，则还原
    ///         如果格子里与拿出的东西容量为1或者不是同种物品或者当前格子满了，则进行物品交换。（如果当前格子是装备格子，则更新人物属性）
    ///         如果格子里与拿出的东西相同且容量不为1且格子未满，则进行判断
    ///             如果放下物品格子不会溢出，则物品合并到当前格子中，清空之前的格子
    ///             如果放下物品格子会溢出，则充满该格子，之前的物品格数量相应减少
    /// 如果是拿出来部分物品
    ///     如果格子是空的，则把物品放入到当前格子，放下。（如果当前格子是装备格子，则更新人物属性）
    ///     如果格子不是空的，则进行判断
    ///         如果格子里与拿出的东西容量为1或者不是同种物品或者当前格子满了，则与拿起物品进行交换。（如果当前格子是装备格子，则更新人物属性）
    ///         如果格子里与拿出的东西相同且容量不为1且格子未满，则进行判断
    ///             如果放下物品格子不会溢出，则物品合并到当前格子中，放下
    ///             如果放下物品格子会溢出，则充满该格子，拿起的物品数量相应减少
    /// </summary>
    /// <param name="pickUpArticle">拿起的物品</param>
    public virtual void PutDown(PickUpArticle pickUpArticle) {
        ArticleManager articleManager = ArticleManager.Instance;
        ArticleItem articleItem = pickUpArticle.ArticleItem;
        ArticleSlot articleSlot = articleItem.GetArticleSlot(); // 拿起的物品之前所在的格子
        Article article = pickUpArticle.ArticleInfo.Article; // 拿起的物品
        int amount = pickUpArticle.ArticleInfo.Amount;
        if (articleSlot.ArticleItem.IsPickUpAll) { // 如果是全部拿出来
            if (this.IsEmpty()) { // 如果是空的
                this.StoreArticle(pickUpArticle.ArticleInfo.Article, pickUpArticle.ArticleInfo.Amount);
                articleSlot.ClearArticle();
                if (articleSlot.ArticleCategory != Constant.ArticleCategory.Anything) { // 之前的格子是装备格子
                    articleManager.UpdatePersonageProp(article, null); // 脱下装备
                }
                if (this.ArticleCategory != Constant.ArticleCategory.Anything) { // 当前格子是装备的格子
                    articleManager.UpdatePersonageProp(null, article); // 穿上装备
                }
            } else { // 不是空的
                ArticleTemplet articleTemplet = article.ArticleTemplet;
                if (this == articleSlot) { // 同一格子中
                    // do nothing
                } else if (articleTemplet.SpaceNum == 1 // 容量为1
                    || !article.ArticleTempletId.Equals(this.ArticleItem.ArticleInfo.Article.ArticleTempletId) // 不是同种物品
                    || this.IsFull) { // 当前格子满了
                    // 进行物品交换
                    articleSlot.SetArticle(articleSlot.ArticleItem, this.ArticleItem.ArticleInfo.Article, this.ArticleItem.ArticleInfo.Amount);
                    this.SetArticle(this.ArticleItem, article, amount);
                    //ArticleManager.Instance.RefreshToolTip(article.Name, article.Intro); // 刷新显示信息
                    if (this.ArticleCategory != Constant.ArticleCategory.Anything) { // 当前格子是装备的格子
                        articleManager.UpdatePersonageProp(articleSlot.ArticleItem.ArticleInfo.Article, article); // 更新装备
                    }
                } else { // 其他情况
                    int all = amount + this.ArticleItem.ArticleInfo.Amount;
                    if (all <= articleTemplet.SpaceNum) { // 没有溢出
                        // 清空之前的格子
                        articleSlot.ClearArticle();
                        // 当前格子增加数量
                        this.StoreArticle(article, amount);
                    } else { // 会溢出
                        // 当前格子充满
                        int num = articleTemplet.SpaceNum - this.ArticleItem.ArticleInfo.Amount; // 变化数量
                        this.StoreArticle(article, num);
                        // 之前格子减去数量
                        articleSlot.SetArticle(articleSlot.ArticleItem, article, articleSlot.ArticleItem.ArticleInfo.Amount - num);
                    }
                }
            }
            pickUpArticle.PutDownAll();
        } else { // 不是全部拿出来
            if (this.IsEmpty()) { // 如果是空的
                this.StoreArticle(pickUpArticle.ArticleInfo.Article, pickUpArticle.ArticleInfo.Amount);
                pickUpArticle.PutDownAll();
                if (this.ArticleCategory != Constant.ArticleCategory.Anything) { // 当前格子是装备的格子
                    articleManager.UpdatePersonageProp(null, article); // 穿上装备
                }
            } else { // 不是空的
                ArticleTemplet articleTemplet = article.ArticleTemplet;
                if (articleTemplet.SpaceNum == 1 // 容量为1
                    || !article.ArticleTempletId.Equals(this.ArticleItem.ArticleInfo.Article.ArticleTempletId) // 不是同种物品
                    || this.IsFull) { // 当前格子满了
                    // 与拿起物品进行交换
                    pickUpArticle.PickUp(this.ArticleItem, this.ArticleItem.ArticleInfo.Amount);
                    this.SetArticle(this.ArticleItem, article, amount);
                    //ArticleManager.Instance.RefreshToolTip(article.Name, article.Intro); // 刷新显示信息
                    //ArticleManager.Instance.RefreshToolTip();
                    if (this.ArticleCategory != Constant.ArticleCategory.Anything) { // 当前格子是装备的格子
                        articleManager.UpdatePersonageProp(pickUpArticle.ArticleInfo.Article, article); // 更新装备
                    }
                } else { // 其他情况
                    int all = amount + this.ArticleItem.ArticleInfo.Amount;
                    if (all <= articleTemplet.SpaceNum) { // 没有溢出
                        // 当前格子增加数量
                        this.StoreArticle(article, amount);
                        pickUpArticle.PutDownAll();
                    } else { // 会溢出
                        // 当前格子充满
                        int num = articleTemplet.SpaceNum - this.ArticleItem.ArticleInfo.Amount; // 变化数量
                        this.StoreArticle(article, num);
                        // 拿起物品减去数量
                        pickUpArticle.PickUp(this.ArticleItem, amount - num);
                    }
                }
            }
        }
        ArticleManager.Instance.RefreshToolTip();
    }

    /// <summary>
    /// 鼠标移入，显示物品提示
    /// </summary>
    /// <param name="eventData"></param>
    public void OnPointerEnter(PointerEventData eventData) {
        if (this.IsNotEmpty()) {
            ArticleManager.Instance.ShowToolTip(this, eventData.position);
        }
    }

    /// <summary>
    /// 鼠标移出，隐藏物品提示
    /// </summary>
    /// <param name="eventData"></param>
    public void OnPointerExit(PointerEventData eventData) {
        ArticleManager.Instance.HideToolTip();
    }

}
